//
//  OrderLogic.m
//  Manager
//
//  Created by 彭凯敏 on 15/8/19.
//  Copyright (c) 2015年 52xiaoluo. All rights reserved.
//

#import "ViewRoomLogic.h"
#import "head.pb.h"
#import "AESCrypt.h"
#import "SecrityLogic.h"
#import "DataBaseOrder.h"
#import "QueueLogic.h"
#import "Message.pb.h"
#import <AVFoundation/AVFoundation.h>

@implementation ViewRoomLogic
{
    NSMutableDictionary *idMap;
    NSMutableDictionary *statsMap;
    //数据库
    UInt64 recordTimeMax;
    UInt64 recordTimeMin;
    DataBaseOrder *db;
}
static ViewRoomLogic* _instance = nil;
+(instancetype) shareInstance
{
    static dispatch_once_t onceToken ;
    dispatch_once(&onceToken, ^{
        _instance = [[ViewRoomLogic alloc] init] ;
    });
    
    return _instance ;
}
-(id)init {
    self = [super init];
    if (self) {
        idMap = [[NSMutableDictionary alloc] init];
        statsMap = [[NSMutableDictionary alloc]init];
        [[UserModuleManager shareInstance] registerUserModule:self];
    }
    return self;
}

#pragma mark - order/viewRoom
- (void)loadDataBase
{
    dispatch_async([[QueueLogic shareInstance]getWorkQueue], ^{
        NSMutableArray *models;
        models =[NSMutableArray arrayWithArray:[db selectAll]];
        [self onRecieveOrders:models isFromDB:true];
    });
}


-(void)userLogin {
    DLog(@"userLogin");
    db = [[DataBaseOrder alloc] initWithDB:[[UserLogic shareInstance] getDBName]];
    [self loadDataBase];
}

-(void)userLogout {
    DLog(@"userLogout");
    [idMap removeAllObjects];
    [statsMap removeAllObjects];
    if (db) {
        [db close];
        db = nil;
    }
}


-(NSArray *) getOrdeModelArrayByStatus:(NSString *)status {
    return statsMap[status];
}


- (NSArray *)getOrderModelArray_1_2
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [array addObjectsFromArray:statsMap[@"1"]];
    [array addObjectsFromArray:statsMap[@"2"]];
    return array;
}


#pragma mark - record
- (NSArray *)getOrderModelArray_6_7
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [array addObjectsFromArray:statsMap[@"6"]];
    [array addObjectsFromArray:statsMap[@"7"]];
    return array;
}


#pragma mark - request

- (void) loadMore:(NSString *)status {
    dispatch_async([[QueueLogic shareInstance]getWorkQueue], ^{
        NSMutableArray *models = statsMap[status];
        unsigned long long min = 0;
        if (models != nil && models.count > 0) {
            ViewOrderModel *last = models[models.count - 1];
            min = last.order.updateTime;
            }
            QueryOrderReqBuilder *builder = [[QueryOrderReqBuilder alloc]init];
            [builder setStatus:status];
            
            if ([@"6" isEqualToString:status]) {
                [builder setStatus:@"6,7"];
                NSMutableArray *models = statsMap[@"7"];
                if (models != nil && models.count > 0) {
                    ViewOrderModel *last = [models lastObject];
                    if (last.order.updateTime < min) {
                        min = last.order.updateTime;
                    }
                }
            }
            [builder setMinUpdateTime:min];
            [[ViewRoomLogic shareInstance]queryOrderReqWithBuild:builder.build];
        
    });
}

- (void) loadNewer:(NSString *)status {
    dispatch_async([[QueueLogic shareInstance]getWorkQueue], ^{
        NSMutableArray *models = statsMap[status];
        unsigned long long  max = 0;
        if (models != nil && models.count > 0) {
            ViewOrderModel *first = models[0];
            max = first.order.updateTime;
        }
        QueryOrderReqBuilder *builder = [[QueryOrderReqBuilder alloc]init];
        [builder setStatus:status];
        if ([@"6" isEqualToString:status]) {
            [builder setStatus:@"6,7"];
            NSMutableArray *models = statsMap[@"7"];
            if (models != nil && models.count > 0) {
                ViewOrderModel *first = models[0];
                if (first.order.updateTime > max) {
                    max = first.order.updateTime;
                }
            }
        }
        [builder setMaxUpdateTime:max];
        [[ViewRoomLogic shareInstance]queryOrderReqWithBuild:builder.build];
    });
}


/**
 *  查询订单
 */
- (void)queryOrderReqWithBuild:(QueryOrderReq *)req
{
    if ([[UserLogic shareInstance] getUserId] <= 0) {
        DLog(@"queryOrderReqWithBuild no login return");
        return;
    }
    [self sendRequest:CMD_ViewRoom_QueryOrder PBMsg:req];
    
}
/**
 *  管家接单
 */
- (void)stewardOrderReqWithBuild:(StewardOrderReq *)req
{
    [self sendRequest:CMD_ViewRoom_StewardOrder PBMsg:req];
}
/**
 *  确认看房
 */
- (void)confirmViewReqWithBuild:(ConfirmViewReq *)req
{
    [self sendRequest:CMD_ViewRoom_ConfirmView PBMsg:req];
}
/**
 *  确认看房
 */
- (void)reViewReqWithBuild:(ConfirmViewReq *)req
{
    [self sendRequest:CMD_ViewRoom_Review PBMsg:req];
}
/**
 *  添加看房
 */
- (void)addViewReqWithBuild:(AddViewReq *)req
{
    [self sendRequest:CMD_ViewRoom_AddViewReq PBMsg:req];
    
}
/**
 *  确认订房
 */
- (void)reserveRoomReqWithBuild:(ReserveRoomReq *)req
{
    [self sendRequest:CMD_ViewRoom_ReserveRoomReq PBMsg:req];
    
}
/**
 *  添加订房
 */
- (void)addReserveRoomReqWithBuild:(AddReserveRoomReq *)req
{
    [self sendRequest:CMD_ViewRoom_AddReserveRoomReq PBMsg:req];
    
}
/**
 *  房间搜索
 */
- (void)roomSearchReqWithBuild:(RoomSearchReq *)req
{
    [self sendRequest:CMD_ViewRoom_RoomSerachReq PBMsg:req];
    
}
/**
 *  Pull数据
 *
 *  @param msgs 数据
 */
- (void)recieveOrderPush:(NSMutableArray *)msgs {
    if (msgs.count > 0) {
        NSMutableArray *array = [[NSMutableArray alloc]init];
        for (int i = (int)msgs.count - 1; i >= 0; i--) {
            Msg *msg = msgs[i];
            NSData *data = msg.msgBody.context;
            ViewOrder *order = [ViewOrder parseFromData:data];
            if (order != nil)
                [array addObject:order];
        }
        if (array.count > 0) {
            
            AudioServicesPlaySystemSound(1007);
            AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
            
            [self onRecieveOrders:[self viewOrdersToViewOrderModel:array] isFromDB:false];
        }
    }
}

-(void)onReceiveViewOrder:(ViewOrder *)order {
    if (order) {
        NSArray *orders = [[NSArray alloc] initWithObjects:order, nil];
        [self onRecieveOrders:[self viewOrdersToViewOrderModel:orders] isFromDB:false];
    }
}

-(NSMutableArray *)onRecieveOrders:(NSArray*)orders isFromDB:(BOOL)isFromDB {
    NSMutableArray *toSave = [[NSMutableArray alloc] init];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    NSMutableSet *statusChangeSet = [[NSMutableSet alloc] init];
    if (orders != nil && orders.count > 0) {
        for (ViewOrderModel *model in orders) {
            ViewOrderModel *old = idMap[@(model.order.id).stringValue];
            if ([model.statusStr isEqualToString:@(ViewOrderStatusOrderIsReceive).stringValue] &&
                model.order.orderStewardId != [[UserLogic shareInstance] getUserId]) {
                if (old != nil) {
                    [statusChangeSet addObject:old.statusStr];
                    [toRemove addObject:old];
                }
                continue;
            }
            ViewOrderModel *new = nil;
            if (old == nil) {
                new = model;
            } else {
                if (model.order.updateTime > old.order.updateTime) {
                    new = model;
                }
            }
            if (new != nil) {
                if (old != nil) {
                    [statusChangeSet addObject:old.statusStr];
                    [toRemove addObject:old];
                }
                [toSave addObject:new];
                [statusChangeSet addObject:new.statusStr];
            }
        }
        
        for (ViewOrderModel *model in toRemove) {
            [idMap removeObjectForKey:@(model.order.id).stringValue];
            NSMutableArray *array = statsMap[model.statusStr];
            if (array != nil) {
                [array removeObject:model];
            }
        }
        
        for (ViewOrderModel *model in toSave) {
            idMap[@(model.order.id).stringValue] = model;
            NSMutableArray *array = statsMap[model.statusStr];
            if (array == nil) {
                array = [[NSMutableArray alloc] init];
                statsMap[model.statusStr] = array;
            }
            [array addObject:model];
        }
        
        if (!isFromDB) {
            for (ViewOrderModel *model in toRemove) {
                DLog("onRecieveViewOrders removeOrder id=%d status=%d ts=%lld ",model.order.id,model.order.status,model.order.updateTime);
                [db deleteWithId:model.order.id];
            }
            
            for (ViewOrderModel *model in toSave) {
                DLog("onRecieveViewOrders saveOrder id=%d status=%d ts=%lld ",model.order.id,model.order.status,model.order.updateTime);
            }
            
            [db insertDBwithViewOrderModelArray:toSave useTransaction:true];
        }
        
        if (statusChangeSet.count > 0) {
            for (NSString *status in statusChangeSet) {
                NSMutableArray *array = statsMap[status];
                if (array != nil) {
                    [self sortOrderDesc:array];
                }
                [[NSNotificationCenter defaultCenter]postNotificationName:Notifi_Order_Data object:status];
            }
        }
    }
    return nil;
}


#pragma mark - RequestDelegate
- (void)onResult:(Packet *)result req:(Request *)req
{
    NSData *plain =[[SecrityLogic shareInstance] decryptSession:result.eBody];

    if([result.cmd isEqualToString:CMD_ViewRoom_QueryOrder])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
            
            
            [[NSNotificationCenter defaultCenter] postNotificationName:Notifi_Order_Data object:model];
            return;
        }
        
        QueryOrderResp *resp = [QueryOrderResp parseFromData:plain];
        DLog(@"description = %@",resp.description);
        
        if (resp.viewOrders.count == 0) {
            [[NSNotificationCenter defaultCenter] postNotificationName:Notifi_Order_Data object:nil];
            return;
        }
        QueryOrderReq *queryReq = (QueryOrderReq *)req.oriPb;
        
        
        if (result.ret == 0) {
            // TODO 有些要删除掉，否则靠时间戳会与server数据不一致
            if ([queryReq.status isEqualToString:@"1,2"]) {
                [statsMap removeObjectForKey:@"1"];
                [statsMap removeObjectForKey:@"2"];
                NSArray *keyArray = [[NSArray alloc] initWithArray:idMap.allKeys];
                for (NSString *id in keyArray) {
                    ViewOrderModel *model = idMap[id];
                    if ([model.statusStr isEqualToString:@"1"] ||
                        [model.statusStr isEqualToString:@"2"]) {
                        [idMap removeObjectForKey:@(model.order.id).stringValue];
                    }
                }
                [db deleteDBwithStatus:@"1"];
                [db deleteDBwithStatus:@"2"];
            } else if ([queryReq.status isEqualToString:@(ViewOrderStatusOrderIsView).stringValue]) {
                [statsMap removeObjectForKey:@(ViewOrderStatusOrderIsView).stringValue];
                NSArray *keyArray = [[NSArray alloc] initWithArray:idMap.allKeys];
                for (NSString *id in keyArray) {
                    ViewOrderModel *model = idMap[id];
                    if ([model.statusStr isEqualToString:@"4"]) {
                        [idMap removeObjectForKey:@(model.order.id).stringValue];
                    }
                }
                [db deleteDBwithStatus:@"4"];
            }
            [self onRecieveOrders:[self viewOrdersToViewOrderModel:resp.viewOrders] isFromDB:false];
        }
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_StewardOrder])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
            [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_StewardOrder object:model];
            return;
        }
        StewardOrderResp *resp = [StewardOrderResp parseFromData:plain];
        DLog(@"StewardOrder %@",resp.description);
        [self onReceiveViewOrder:resp.viewOrder];
        [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_StewardOrder object:resp.viewOrder];
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_ConfirmView])
    {
        
        ConfirmViewReq *confirmReq = (ConfirmViewReq *)req.oriPb;
        if (confirmReq.isView == YES) {//确认看房
            if (result.ret != 0) {
                DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
                [[NSNotificationCenter defaultCenter]postNotificationName:Notifi_ConfirmView object:model];
                return;
            }
            ConfirmViewResp *resp = [ConfirmViewResp parseFromData:plain];
            DLog(@"AddViewReq %@",resp.description);
            [self onReceiveViewOrder:resp.viewOrder];
            [[NSNotificationCenter defaultCenter]postNotificationName:Notifi_ConfirmView object:resp.viewOrder];
        }
        else
        {
            if (result.ret != 0) {
                DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
                [[NSNotificationCenter defaultCenter]postNotificationName:Notifi_ConfirmView_GiveUp object:model];
                return;
            }
            ConfirmViewResp *resp = [ConfirmViewResp parseFromData:plain];
            DLog(@"AddViewReq %@",resp.description);
            [self onReceiveViewOrder:resp.viewOrder];
            [[NSNotificationCenter defaultCenter]postNotificationName:Notifi_ConfirmView_GiveUp object:resp.viewOrder];
        }
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_Review])//重新预约
    {
        
        ConfirmViewReq *confirmReq = (ConfirmViewReq *)req.oriPb;
        if (confirmReq.isView == YES) {//确认看房
            if (result.ret != 0) {
                DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
                [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_Review object:model];
                return;
            }
            ConfirmViewResp *resp = [ConfirmViewResp parseFromData:plain];
            DLog(@"AddViewReq %@",resp.description);
            [self onReceiveViewOrder:resp.viewOrder];
            [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_Review object:resp.viewOrder];
        }
    }
    
    else if ([result.cmd isEqualToString:CMD_ViewRoom_AddViewReq])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
             [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_AddViewReq object:model];
            return;
        }
        AddViewResp *resp = [AddViewResp parseFromData:plain];
        DLog(@"AddViewReq %@",resp.description);
        [self onReceiveViewOrder:resp.viewOrder];
        
        [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_AddViewReq object:resp.viewOrder];
            
            
         
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_ReserveRoomReq])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
            [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_ReserveRoomReq object:model];
            return;
        }
        AddViewResp *resp = [AddViewResp parseFromData:plain];
        DLog(@"ReserveRoomReq viewOrder%@",resp.viewOrder);
         [self onReceiveViewOrder:resp.viewOrder];
        [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_ReserveRoomReq object:resp.viewOrder];
            
            
         
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_AddReserveRoomReq])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
            [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_ReserveRoomReq object:model];
            return;
        }
        AddReserveRoomResp *resp = [AddReserveRoomResp parseFromData:plain];
        DLog(@"ReserveRoomReq viewOrder%@",resp.viewOrder);
        [self onReceiveViewOrder:resp.viewOrder];
        [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_ReserveRoomReq object:resp.viewOrder];
        
        
    }
    else if ([result.cmd isEqualToString:CMD_ViewRoom_RoomSerachReq])
    {
        if (result.ret != 0) {
            DLog(@"error,ret=%d error=%@",result.ret,result.error);
            ErrorModel *model = [[ErrorModel alloc]init];
            model.ret = [NSString stringWithFormat:@"%d",result.ret];
            model.error = result.error;
            [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_RoomSerachReq object:model];
            return;
        }
        RoomSearchResp *resp = [RoomSearchResp parseFromData:plain];
        DLog(@"RoomSerachReq %@",resp.description);
        [[NSNotificationCenter defaultCenter]postNotificationName:CMD_ViewRoom_RoomSerachReq object:resp.rooms];
    }

}


- (NSArray *)viewOrdersToViewOrderModel:(NSArray *)viewOrders
{
    if (viewOrders == nil)
        return @[];
    NSMutableArray *newArray = [[NSMutableArray alloc]init];
    for (ViewOrder *order in viewOrders) {
        ViewOrderModel *model = [ViewOrderModel fromOrderVew:order];
        [newArray addObject:model];
    }
    return newArray;
}
                                 
                                 
//降序排序
- (void)sortOrderDesc:(NSMutableArray *)array
{
     [array sortUsingComparator:
                              ^NSComparisonResult(ViewOrderModel *obj2, ViewOrderModel *obj1) {
                                  //                                   先按照time排序
                                  NSNumber *number1 = [NSNumber numberWithLongLong:obj1.order.updateTime];
                                  NSNumber *number2 = [NSNumber numberWithLongLong:obj2.order.updateTime];
                                  NSComparisonResult result = [number1 compare:number2];
                                return result;
                              }
     ];
}

@end
